package com.wiscamp.ninechapters.panels.application.services;

import com.wiscamp.ninechapters.panels.application.assemblers.PermissionAssembler;
import com.wiscamp.ninechapters.panels.application.command.CreatePermissionCommand;
import com.wiscamp.ninechapters.panels.application.command.UpdatePermissionCommand;
import com.wiscamp.ninechapters.panels.application.vo.PermissionVO;
import com.wiscamp.ninechapters.panels.domain.repositories.PermissionRepository;
import com.wiscamp.ninechapters.panels.domain.services.PermissionService;
import cube.ddd.application.BaseAppService;
import cube.ddd.application.command.DeleteCommand;
import cube.ddd.application.command.DisableCommand;
import cube.ddd.application.command.EnableCommand;
import cube.ddd.aspect.HandleServiceException;
import cube.ddd.common.query.PagedObjects;
import cube.ddd.common.query.PagedQuery;
import cube.ddd.utils.AppServiceUtils;
import jakarta.validation.Valid;
import org.springframework.stereotype.Service;

import java.util.Collection;

@Service
public class PermissionAppService extends BaseAppService {

    private final PermissionRepository permissionRepository;

    private final PermissionService permissionService;

    public PermissionAppService(PermissionRepository permissionRepository, PermissionService permissionService) {
        this.permissionRepository = permissionRepository;
        this.permissionService = permissionService;
    }

    @HandleServiceException
    public PermissionVO getPermission(long permissionId) {
        return AppServiceUtils.getById(permissionId, permissionService::getPermission,
                PermissionAssembler.Instance::toPermissionVO);
    }

    @HandleServiceException
    public PermissionVO getPermissionByCode(long appId, String permissionCode) {
        return AppServiceUtils.getByIdAndText(appId, permissionCode, permissionRepository::getPermissionByCode,
                PermissionAssembler.Instance::toPermissionVO);
    }

    @HandleServiceException
    public Collection<PermissionVO> getPermissionsByName(long appId, String permissionName) {
        return AppServiceUtils.getListByIdAndText(appId, permissionName, permissionRepository::getPermissionsByName,
                PermissionAssembler.Instance::toPermissionVO);
    }

    @HandleServiceException
    public Collection<PermissionVO> getPermissionsByGroup(long appId, String appGroup) {
        return AppServiceUtils.getListByIdAndText(appId, appGroup, permissionRepository::getPermissionsByGroup,
                PermissionAssembler.Instance::toPermissionVO);
    }

    @HandleServiceException
    public PagedObjects<PermissionVO> getPermissionsByQuery(PagedQuery pagedQuery) {
        var pagedObjects = permissionRepository.getPermissionsByQuery(pagedQuery);
        return AppServiceUtils.convertPagedObjects(pagedObjects, PermissionAssembler.Instance::toPermissionVO);
    }

    @HandleServiceException
    public PermissionVO createPermission(@Valid CreatePermissionCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.createOrUpdateBy(command, command.getOperatorId(), permissionService::createPermission,
                PermissionAssembler.Instance::toPermissionVO, PermissionAssembler.Instance::fromCreateCommand);
    }

    @HandleServiceException
    public PermissionVO updatePermission(@Valid UpdatePermissionCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.createOrUpdateBy(command, command.getOperatorId(), permissionService::updatePermission,
                PermissionAssembler.Instance::toPermissionVO, PermissionAssembler.Instance::fromUpdateCommand);
    }

    @HandleServiceException
    public boolean deletePermission(@Valid DeleteCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.delete(command.getId(), command.getOperatorId(), permissionService::deletePermission);
    }

    @HandleServiceException
    public boolean enablePermission(@Valid EnableCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.enable(command.getId(), command.getOperatorId(), permissionService::enablePermission);
    }

    @HandleServiceException
    public boolean disablePermission(@Valid DisableCommand command) {
        command.setOperatorId(getCurrentUserId());
        return AppServiceUtils.disable(command.getId(), command.getOperatorId(), permissionService::disablePermission);
    }
}
